/**
 * Generali Solutions d'assurances - Tous droits réservés &copy; 2007 - 2010
 */
package fr.generali.accueilclient.client.assembler.output.p2bis;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;

import fr.generali.accueilclient.client.assembler.output.DonneesContactMapper;
import fr.generali.accueilclient.client.om.IClientAssociation;
import fr.generali.accueilclient.client.om.IClientAutre;
import fr.generali.accueilclient.client.om.IClientCollectivite;
import fr.generali.accueilclient.client.om.IClientCopropriete;
import fr.generali.accueilclient.client.om.IClientEntreprise;
import fr.generali.accueilclient.client.om.IClientParticulier;
import fr.generali.accueilclient.client.om.IClientProfessionnel;
import fr.generali.accueilclient.client.om.IPersonne;
import fr.generali.accueilclient.client.om.IPersonneMorale;
import fr.generali.accueilclient.client.om.IPersonnePhysique;
import fr.generali.accueilclient.client.om.NaturePersonne;
import fr.generali.refservcommuns.rce.rechpersgen.extrait.DtoDossierPersonneExtrait;
import fr.generali.refservcommuns.rce.rechpersgen.extrait.DtoExtraitPersonneMorale;
import fr.generali.refservcommuns.rce.rechpersgen.extrait.DtoExtraitPersonnePhysique;

/**
 * Transforme un {@link DtoDossierPersonneExtrait} en {@link IPersonne}
 * 
 * @author Guillaume Lancelin
 */
@Component("dtoDossierPersonneExtrait2PersonneConverter")
public class DtoDossierPersonneExtrait2PersonneConverter implements
    Converter<DtoDossierPersonneExtrait, IPersonne> {

    /**
     * LOGGER
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(DtoDossierPersonneExtrait2PersonneConverter.class);

    /**
     * Assembler de personne physique
     */
    @Autowired
    @Qualifier("dtoExtraitPersonnePhysique2PersonnePhysiqueConverter")
    private Converter<DtoExtraitPersonnePhysique, IPersonnePhysique> dtoExtraitPersonnePhysique2PersonnePhysiqueConverter;

    /**
     * Assembler de personne morale
     */
    @Autowired
    @Qualifier("dtoExtraitPersonneMorale2PersonneMoraleConverter")
    private Converter<DtoExtraitPersonneMorale, IPersonneMorale> dtoExtraitPersonneMorale2PersonneMoraleConverter;

    /**
     * Assembler pour un particulier
     */
    @Autowired
    @Qualifier("dtoDossierPersonneExtrait2ClientParticulierConverter")
    private Converter<DtoDossierPersonneExtrait, IClientParticulier> dtoDossierPersonneExtrait2ClientParticulierConverter;

    /**
     * Assembler pour un pro
     */
    @Autowired
    @Qualifier("dtoDossierPersonneExtrait2ClientProfessionnelConverter")
    private Converter<DtoDossierPersonneExtrait, IClientProfessionnel> dtoDossierPersonneExtrait2ClientProfessionnelConverter;

    /**
     * Assembler pour une association
     */
    @Autowired
    @Qualifier("dtoDossierPersonneExtrait2ClientAssociationConverter")
    private Converter<DtoDossierPersonneExtrait, IClientAssociation> dtoDossierPersonneExtrait2ClientAssociationConverter;

    /**
     * Assembler pour une collectivité
     */
    @Autowired
    @Qualifier("dtoDossierPersonneExtrait2ClientCollectiviteConverter")
    private Converter<DtoDossierPersonneExtrait, IClientCollectivite> dtoDossierPersonneExtrait2ClientCollectiviteConverter;

    /**
     * Assembler pour une copropriété
     */
    @Autowired
    @Qualifier("dtoDossierPersonneExtrait2ClientCoproprieteConverter")
    private Converter<DtoDossierPersonneExtrait, IClientCopropriete> dtoDossierPersonneExtrait2ClientCoproprieteConverter;

    /**
     * Assembler pour une entreprise
     */
    @Autowired
    @Qualifier("dtoDossierPersonneExtrait2ClientEntrepriseConverter")
    private Converter<DtoDossierPersonneExtrait, IClientEntreprise> dtoDossierPersonneExtrait2ClientEntrepriseConverter;

    /**
     * Assembler pour tout autre type de client
     */
    @Autowired
    @Qualifier("dtoDossierPersonneExtrait2ClientAutreConverter")
    private Converter<DtoDossierPersonneExtrait, IClientAutre> dtoDossierPersonneExtrait2ClientAutreConverter;

    /**
     * Permet de mapper adresse, téléphone et email
     */
    @Autowired
    private DonneesContactMapper donneesContactMapper;

    /**
     * {@inheritDoc}
     */
    public IPersonne convert(DtoDossierPersonneExtrait input) {
        LOGGER.info("assemble");

        DtoExtraitPersonnePhysique personnePhysique = input.getPersonnePhysique();
        DtoExtraitPersonneMorale personneMorale = input.getPersonneMorale();
        
//        boolean isPersonnePhysique = personneMorale == null && personnePhysique != null;
//        boolean isPersonneMorale = personneMorale != null;
//        boolean isPersonnePro = personneMorale != null && personnePhysique != null;
        
        NaturePersonne nature = NaturePersonne.PARTICULIER;
        if (personneMorale != null && personnePhysique != null) {
            nature = NaturePersonne.PROFESSIONNEL;
        } else if (personneMorale != null) {
            nature = NaturePersonne.getNaturePersonneFromValue(personneMorale.getTypePersonneMorale());
        }

        IPersonne client = buildClient(input, nature);
        
        if (NaturePersonne.PARTICULIER.equals(nature) || NaturePersonne.PROFESSIONNEL.equals(nature)) {
            // Récupération des informations du niveau IPersonnePhysique
            IPersonnePhysique.class.cast(client).setPersonnePhysique(
                            dtoExtraitPersonnePhysique2PersonnePhysiqueConverter.convert(personnePhysique));
            // Récupération des informations du niveau IPersonne
            client.setNumeroClient(personnePhysique.getIdentifiantPersonne());
            if (personnePhysique.getVisibilite() != null) { 
                if (StringUtils.isNotEmpty(personnePhysique.getVisibilite().getIdentifiantClientAgent())) {
                    client.setNumeroClientAgent(personnePhysique.getVisibilite().getIdentifiantClientAgent());
                }
                client.setCodeIntermediaire(personnePhysique.getVisibilite().getIdentifiantIntermediaire());
                client.setPointDeVente(personnePhysique.getVisibilite().getIdentifiantPointVente());
                client.setChargeClientele(personnePhysique.getVisibilite().getIdentifiantChargeClientele());
            }
            client.setTypeClient(personnePhysique.getStatutClient());
            client.setAdressePrincipale(donneesContactMapper.getAdressePrincipale(personnePhysique
                            .getAdressePrincipale()));
        } else {
            // Récupération des informations du niveau IPersonneMorale
            IPersonneMorale.class.cast(client).setPersonneMorale(
                            dtoExtraitPersonneMorale2PersonneMoraleConverter.convert(personneMorale));
            // Récupération des informations du niveau IPersonne
            if (personneMorale.getIdentifiantPersonne().startsWith("PM")) {
                client.setNumeroClient(personneMorale.getIdentifiantPersonne().substring(2));
            } else {
                client.setNumeroClient(personneMorale.getIdentifiantPersonne());
            }
            if (personneMorale.getVisibilite() != null) { 
                if (StringUtils.isNotEmpty(personneMorale.getVisibilite().getIdentifiantClientAgent())) {
                    client.setNumeroClientAgent(personneMorale.getVisibilite().getIdentifiantClientAgent());
                }
                client.setCodeIntermediaire(personneMorale.getVisibilite().getIdentifiantIntermediaire());
                client.setPointDeVente(personneMorale.getVisibilite().getIdentifiantPointVente());
                client.setChargeClientele(personneMorale.getVisibilite().getIdentifiantChargeClientele());
            }
            client.setTypeClient(personneMorale.getStatutClient());
            client.setAdressePrincipale(donneesContactMapper
                            .getAdressePrincipale(personneMorale.getAdressePrincipale()));
        }
        
        return client;
    }

    /**
     * @param input un {@link DtoDossierPersonneExtrait}
     * @param nature la nature personne
     * @return une personne
     */
    private IPersonne buildClient(DtoDossierPersonneExtrait input, NaturePersonne nature) {
        IPersonne client;
        switch (nature) {
            case PARTICULIER:
                client = dtoDossierPersonneExtrait2ClientParticulierConverter.convert(input);
                break;
            case PROFESSIONNEL:
                client = dtoDossierPersonneExtrait2ClientProfessionnelConverter.convert(input);
                break;
            case ASSOCIATION:
                client = dtoDossierPersonneExtrait2ClientAssociationConverter.convert(input);
                break;
            case COLLECTIVITE:
                client = dtoDossierPersonneExtrait2ClientCollectiviteConverter.convert(input);
                break;
            case COPROPRIETE:
                client = dtoDossierPersonneExtrait2ClientCoproprieteConverter.convert(input);
                break;
            case ENTREPRISE:
                client = dtoDossierPersonneExtrait2ClientEntrepriseConverter.convert(input);
                break;
            default:
                client = dtoDossierPersonneExtrait2ClientAutreConverter.convert(input);
                break;
        }
        return client;
    }
}
